package cn.com.jdyun.service.impl;

import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.com.jdyun.mapper.ext.ExtSysConfigMapper;
import cn.com.jdyun.pojo.SysConfig;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.jdyun.exception.BdexGatewayException;
import cn.com.jdyun.mapper.ext.ExtRefereeMapper;
import cn.com.jdyun.pojo.Referee;
import cn.com.jdyun.pojo.User;
import cn.com.jdyun.pojo.UserWallet;
import cn.com.jdyun.service.RefereeService;
import cn.com.jdyun.service.UserService;
import cn.com.jdyun.util.Constant;
import cn.com.jdyun.util.RedisUtil;

@Service
public class RefereeServiceImpl implements RefereeService {


    private static final Logger logger = LoggerFactory.getLogger(RefereeServiceImpl.class);
    @Autowired
    private ExtRefereeMapper refereeMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private ExtSysConfigMapper sysConfigMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(String userId, String refereeId) throws BdexGatewayException {
        Date cur = new Date();
        //保存一级推荐关系
        Referee referee = new Referee();
        referee.setUserId(userId);
        referee.setRefereeId(refereeId);
        referee.setCreateTime(cur);
        referee.setUpdateTime(cur);
        String context = "";
        if (StringUtils.isNotBlank(refereeId)) {
            Referee pr = refereeMapper.selectUser(refereeId);
            if (pr != null) {
                //保存二级推荐关系
                referee.setRefereeParentId(pr.getRefereeId());
                context = pr.getContext() + userId + "/";
            } else {
                context = "/" + userId + "/";
            }
        } else {
            context = "/" + userId + "/";
        }
        // 保存自己的树节点关系
        referee.setContext(context);
        refereeMapper.insert(referee);
    }

    @Transactional(readOnly = true)
    @Override
    public List<User> userReferees(String userId) throws BdexGatewayException {
        return refereeMapper.selectReferees(userId);
    }

    @Transactional(readOnly = true)
    @Override
    public User userReferee(String userId) throws BdexGatewayException {
        return refereeMapper.selectReferee(userId);
    }

    @Transactional(readOnly = true)
    @Override
    public boolean checkPartner(String userId) throws BdexGatewayException {
    	String redisResult = redisUtil.hget("refereeService.isPartner", userId);
        SysConfig smallMinerConfig = sysConfigMapper.selectByCode(Constant.smallMiner);
        SysConfig strongMiningRewardPercentConfig = sysConfigMapper.selectByCode(Constant.strongMiningRewardPercent);
        SysConfig strongNumLimitConfig = sysConfigMapper.selectByCode(Constant.STRONG_NUM_LIMIT);
        SysConfig superNodeLimitConfig = sysConfigMapper.selectByCode(Constant.SUPERNODE_LIMIT);
    	if(redisResult != null) {
    		return Boolean.valueOf(redisResult);
    	}
    	User user = userService.getById(userId);
    	//用户等级:0 未设置，1，注册会员，2，小矿机，3，大矿机，4，超级节点，5合伙人
    	Boolean result = false;
    	if(user.getLevel() == 0) {

    		result = refereeMapper.isPartner(userId, Constant.COINTYPE_SSSP, smallMinerConfig.getInitValue(), strongMiningRewardPercentConfig.getInitValue(), superNodeLimitConfig.getInitValue(),Integer.valueOf(strongNumLimitConfig.getInitValue()));
        	if(result == null) {
        		result = false;
        	}
    	}else {
    		result = user.getLevel() == 5;
    	}
    	
    	//缓存60分钟
    	redisUtil.hset("refereeService.isPartner", userId, Boolean.valueOf(result).toString(), 60*60*1000);
    	return result;
    }
    
    @Transactional(readOnly = true)
    @Override
	public boolean checkSuperNode(String userId,String coinType) throws BdexGatewayException {
        SysConfig smallMinerConfig = sysConfigMapper.selectByCode(Constant.smallMiner);
        SysConfig texSmallMinerConfig = sysConfigMapper.selectByCode(Constant.texSmallMiner);
        SysConfig texStrongNumLimitconfig = sysConfigMapper.selectByCode(Constant.TEX_STRONG_NUM_LIMIT);
        SysConfig strongNumLimitConfig = sysConfigMapper.selectByCode(Constant.STRONG_NUM_LIMIT);
        SysConfig texSupernodelimitConfig = sysConfigMapper.selectByCode(Constant.TEX_SUPERNODE_LIMIT);
        SysConfig superNodeLimitConfig = sysConfigMapper.selectByCode(Constant.SUPERNODE_LIMIT);
        User user = userService.getById(userId);
        Boolean result = false;
        String redisResult = null;
        if(StringUtils.isEmpty(coinType)){
            throw new BdexGatewayException("代币种类不能为空!");
        }
        if(Constant.COINTYPE_TEX.equals(coinType)){
            redisResult = redisUtil.hget("refereeService.checkSuperNode.tex", userId);
            //用户等级:0 未设置，1，注册会员，2，小矿机，3，大矿机，4，超级节点，5合伙人
            if(user.getFlag() == 0) {
                result = refereeMapper.isSuperNode(userId, Constant.COINTYPE_TEX,texSmallMinerConfig.getInitValue(), texSupernodelimitConfig.getInitValue(), Integer.valueOf(texStrongNumLimitconfig.getInitValue()));
                if(result == null) {
                    result = false;
                }
            }else {
                result = user.getLevel() == 4;
            }
            //缓存60分钟
            redisUtil.hset("refereeService.checkSuperNode.tex", userId, Boolean.valueOf(result).toString(), 60*60*1000);
        }else if(Constant.COINTYPE_SSSP.equals(coinType)){
            redisResult = redisUtil.hget("refereeService.checkSuperNode.sssp", userId);
            //用户等级:0 未设置，1，注册会员，2，小矿机，3，大矿机，4，超级节点，5合伙人
            if(user.getFlag() == 0) {
                result = refereeMapper.isSuperNode(userId, Constant.COINTYPE_SSSP, smallMinerConfig.getInitValue(),superNodeLimitConfig.getInitValue(), Integer.valueOf(strongNumLimitConfig.getInitValue()));
                if(result == null) {
                    result = false;
                }
            }else {
                result = user.getLevel() == 4;
            }
            //缓存60分钟
            redisUtil.hset("refereeService.checkSuperNode.sssp", userId, Boolean.valueOf(result).toString(), 60*60*1000);
        }
        if(redisResult != null) {
            return Boolean.valueOf(redisResult);
        }

    	return result;
	}

    @Transactional(readOnly = true)
    @Override
    public List<UserWallet> queryAllUserWallet(String userId) throws BdexGatewayException {
        List<UserWallet> userWalletList = refereeMapper.queryAllUserWallet(userId, Constant.COINTYPE_SSSP);
        if (userWalletList != null && userWalletList.size() > 0) {
            return userWalletList;
        } else {
            throw new BdexGatewayException("没有查询到其下级信息");
        }
    }

    @Override
    public Set<String> queryAllSuperNodeId() throws BdexGatewayException {
        SysConfig smallMinerConfig = sysConfigMapper.selectByCode(Constant.smallMiner);
        SysConfig strongNumLimitConfig = sysConfigMapper.selectByCode(Constant.STRONG_NUM_LIMIT);
        SysConfig supernodelimitConfig = sysConfigMapper.selectByCode(Constant.SUPERNODE_LIMIT);
    	//查询所有的设置的超级节点
    	Set<String> result1 = userService.queryUserIdByLevel(4);
    	//查询未设置的超级节点
    	Set<String> result2 = refereeMapper.queryAllSuperNodeId(Constant.COINTYPE_SSSP, smallMinerConfig.getInitValue(),supernodelimitConfig.getInitValue(), Integer.valueOf(strongNumLimitConfig.getInitValue()));
    	//更新用户的等级
        for(String str: result2){
            int result = refereeMapper.updateLevel(str,4);
            if(result<=0){
                logger.info("用户ID:"+str+" 等级设置失败!");
            }
        }
    	if(result1 == null) {
    		result1 = new HashSet<>();
    	}
    	result1.addAll(result2);
        return result1;
    }

    @Override
    public Set<String> queryAllTexSuperNodeId() throws BdexGatewayException {
        SysConfig texSmallMinerConfig = sysConfigMapper.selectByCode(Constant.texSmallMiner);
        SysConfig texStrongNumLimitConfig = sysConfigMapper.selectByCode(Constant.TEX_STRONG_NUM_LIMIT);
        SysConfig texSupernodeLimitConfig = sysConfigMapper.selectByCode(Constant.TEX_SUPERNODE_LIMIT);
        //查询所有的设置的超级节点
        Set<String> texResult1 = userService.queryUserIdByTexLevel(4);
        //查询未设置的超级节点
        Set<String> texResult2 = refereeMapper.queryAllSuperNodeId(Constant.COINTYPE_TEX,texSmallMinerConfig.getInitValue(),texSupernodeLimitConfig.getInitValue(), Integer.valueOf(texStrongNumLimitConfig.getInitValue()));
        //更新用户的等级
        for(String str: texResult2){
            int result = refereeMapper.updateTexLevel(str,4);
            if(result<=0){
                logger.info("用户ID:"+str+" 等级设置失败!");
            }
        }
        if(texResult1 == null) {
            texResult1 = new HashSet<>();
        }
        texResult1.addAll(texResult2);
        return texResult1;
    }
    @SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	@Override
	public Set<String> queryAllPartnerId(Set<String> superNodeIds) throws BdexGatewayException {
        SysConfig strongMiningRewardPercentConfig = sysConfigMapper.selectByCode(Constant.strongMiningRewardPercent);
        SysConfig strongNumlimitConfig = sysConfigMapper.selectByCode(Constant.STRONG_NUM_LIMIT);
    	if(superNodeIds == null || superNodeIds.size() == 0) {
    		return Collections.EMPTY_SET;
    	}
    	//查询设置的合伙人
    	Set<String> result1 = userService.queryUserIdByLevel(5);
    	//查询未设置的合伙人
    	Set<String> result2 = refereeMapper.queryAllPartnerId(Constant.COINTYPE_SSSP, superNodeIds,strongMiningRewardPercentConfig.getInitValue(), Integer.valueOf(strongNumlimitConfig.getInitValue()));
        //更新用户的等级
        for(String str: result2){
            int result = refereeMapper.updateLevel(str,5);
            if(result<=0){
                logger.info("用户ID:"+str+" 等级设置失败!");
            }
        }
    	if(result1 == null) {
    		result1 = new HashSet<>();

    	}
    	result1.addAll(result2);
        return result1;
	}
    @SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	@Override
	public Set<String> queryAllTexPartnerId(Set<String> superTexNodeIds) throws BdexGatewayException {
        SysConfig texStrongMiningRewardPercentConfig = sysConfigMapper.selectByCode(Constant.texStrongMiningRewardPercent);
        SysConfig texStrongNumLimitConfig = sysConfigMapper.selectByCode(Constant.TEX_STRONG_NUM_LIMIT);
    	if(superTexNodeIds == null || superTexNodeIds.size() == 0) {
    		return Collections.EMPTY_SET;
    	}
    	//查询设置的合伙人
    	Set<String> result1 = userService.queryUserIdByTexLevel(5);
    	//查询未设置的合伙人
    	Set<String> result2 = refereeMapper.queryAllPartnerId(Constant.COINTYPE_TEX, superTexNodeIds, texStrongMiningRewardPercentConfig.getInitValue(), Integer.valueOf(texStrongNumLimitConfig.getInitValue()));
        //更新用户的等级
        for(String str: result2){
            int result = refereeMapper.updateTexLevel(str,5);
            if(result<=0){
                logger.info("用户ID:"+str+" 等级设置失败!");
            }
        }
    	if(result1 == null) {
    		result1 = new HashSet<>();

    	}
    	result1.addAll(result2);
        return result1;
	}

    @Transactional(readOnly = true)
    @Override
    public int selectLevel1Amount(String userId) throws BdexGatewayException {
        return refereeMapper.selectLevel1Amount(userId);
    }

    @Transactional(readOnly = true)
    @Override
    public int selectLevel2Amount(String userId) throws BdexGatewayException {
        return refereeMapper.selectLevel2Amount(userId);
    }
}
